package com.xf.auth.controller;

import com.alibaba.fastjson.JSON;
import com.nimbusds.jose.jwk.JWKSet;
import com.nimbusds.jose.jwk.RSAKey;
import com.xf.common.core.entity.FebsResponse;
import com.xf.auth.entity.OauthClientDetails;
import com.xf.auth.service.OauthClientDetailsService;
import com.xf.common.core.entity.QueryRequest;
import com.xf.auth.exception.FebsException;
import com.xf.common.core.utils.FebsUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.jwt.Jwt;
import org.springframework.security.jwt.JwtHelper;
import org.springframework.security.jwt.crypto.sign.RsaVerifier;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.validation.Valid;
import javax.validation.constraints.NotBlank;
import java.security.KeyPair;
import java.security.interfaces.RSAPublicKey;
import java.util.Map;

/**
 * @author Yuuki
 */
@Slf4j
@Validated
@RestController
@RequestMapping("client")
public class OauthClientDetailsController {
    @Resource
    private OauthClientDetailsService oauthClientDetailsService;
    @Resource
    private KeyPair keyPair;


    @GetMapping("check/{clientId}")
    public boolean checkUserName(@NotBlank(message = "{required}") @PathVariable String clientId) {
        OauthClientDetails client = this.oauthClientDetailsService.findById(clientId);
        return client == null;
    }

    @GetMapping("secret/{clientId}")
    @PreAuthorize("hasAuthority('client:decrypt')")
    public FebsResponse getOriginClientSecret(@NotBlank(message = "{required}") @PathVariable String clientId) {
        OauthClientDetails client = this.oauthClientDetailsService.findById(clientId);
        String origin = client != null ? client.getOriginSecret() : StringUtils.EMPTY;
        return new FebsResponse().data(origin);
    }

    @GetMapping
    @PreAuthorize("hasAuthority('client:view')")
    public FebsResponse oauthCliendetailsList(QueryRequest request, OauthClientDetails oAuthClientDetails) {
        Map<String, Object> dataTable = FebsUtil.getDataTable(this.oauthClientDetailsService.findOauthClientDetails(request, oAuthClientDetails));
        return new FebsResponse().data(dataTable);
    }


    @PostMapping
   @PreAuthorize("hasAuthority('client:add')")
    public void addOauthCliendetails(@Valid OauthClientDetails oAuthClientDetails) throws FebsException {
        try {
            this.oauthClientDetailsService.createOauthClientDetails(oAuthClientDetails);
        } catch (Exception e) {
            String message = "新增客户端失败";
            log.error(message, e);
            throw new FebsException(message);
        }
    }

    @DeleteMapping
    @PreAuthorize("hasAuthority('client:delete')")
    public void deleteOauthCliendetails(@NotBlank(message = "{required}") String clientIds) throws FebsException {
        try {
            this.oauthClientDetailsService.deleteOauthClientDetails(clientIds);
        } catch (Exception e) {
            String message = "删除客户端失败";
            log.error(message, e);
            throw new FebsException(message);
        }
    }

    @PutMapping
    @PreAuthorize("hasAuthority('client:update')")
    public void updateOauthCliendetails(@Valid OauthClientDetails oAuthClientDetails) throws FebsException {
        try {
            this.oauthClientDetailsService.updateOauthClientDetails(oAuthClientDetails);
        } catch (Exception e) {
            String message = "修改客户端失败";
            log.error(message, e);
            throw new FebsException(message);
        }
    }

    /**
     * 获取公钥
     * @return
     */
    @GetMapping("/public-key")
    public Map<String, Object> getPublicKey() {
        RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
        com.nimbusds.jose.jwk.RSAKey key = new RSAKey.Builder(publicKey).build();
        return new JWKSet(key).toJSONObject();
    }

    public void encode(String accessToken){
        //通过公钥校验jwt令牌
        Jwt jwt = JwtHelper.decodeAndVerify(accessToken, new RsaVerifier("-----BEGIN PUBLIC KEY-----\n" +
                "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAkVialdAhS5YHW+FdpQGf\n" +
                "b+7iiF3JCo9EtKvPB/WxnkJwP9xe27PP/b9NTPKuRrq8nrGtTEGJC1Yba88jXGLI\n" +
                "fTfIKRFZjyKrz9r4SlEfDEHhrPukURa27tohJdtbHrWCRX1mG0MIf46Hig4s90Cw\n" +
                "gKkppzzNnohqGFrZmJ8dVw1bdExw70TeosRxXs0ROgYjINKMDKwpmuxQhZSxWrSi\n" +
                "xljX4ZcV2Ct3WzZnSwST76P9/IHBFDgsvwNnA/M8xZB3+MovGMhsf1WqDiBN6QMM\n" +
                "m5YlLXOjWgzjKQsceMvb57rDSb2aYgnFjWabQetUPkiCJRlnJw3Cy+opCdIBpZO/\n" +
                "DQIDAQAB\n" +
                "-----END PUBLIC KEY-----\n"));
        //拿到jwt令牌中自定义的内容
        Map<String, Object> claims =  JSON.parseObject(jwt.getClaims(),Map.class);
    }

}
